package com.kye.express.business.jd.shop;

import android.util.Pair;

import com.kye.express.business.jd.shop.model.JDGoodsCategoryModel;
import com.kye.express.business.jd.shop.model.JDGoodsItemModel;
import com.kye.express.business.jd.shop.model.JDIntegralModel;
import com.kye.express.business.jd.shop.model.JDTitleModel;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.IView;
import com.kye.model.UserSession;
import com.kye.model.base.PageInfo;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.integral.IntegralUserBean;
import com.kye.model.bean.integral.request.RequestUserIntegral;
import com.kye.model.bean.jd.shop.JDGoodsCategoryBean;
import com.kye.model.bean.jd.shop.JDGoodsItemBean;
import com.kye.model.bean.jd.shop.JDGoodsListResultBean;
import com.kye.model.bean.jd.shop.request.RequestJDGoodsCategories;
import com.kye.model.bean.jd.shop.request.RequestJDGoodsList;
import com.kye.model.bean.user.User;
import com.kye.model.datasource.IntegralDataSource;
import com.kye.model.datasource.JDShopDataSource;
import com.kye.model.gson_adapter.ApiException;
import com.kye.base.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;

import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.SingleSource;
import io.reactivex.SingleTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Function3;
import io.reactivex.schedulers.Schedulers;
import me.drakeet.multitype.MultiTypeAdapter;

/**
 * @author : Joe
 * @version : 1.0
 * @editor : Joe
 * @created : 27/01/2018
 * @updated : 27/01/2018
 * @description : <Description>
 * @update_reason : <UpdateReason>
 */

public class JDShopConstract {

    public interface JDShopView extends IView {

        void onUser(User user);

        void onLoading();

        void onLoaded();

        void refreshInitSuccess(Pair<List<Object>,Boolean> datas);

        void refreshInitServerError(Throwable e);

        void refreshInitNetError(Throwable e);

        void refreshSuccess(Pair<List<Object>,Boolean> datas);

        void refreshServerError(Throwable e);

        void refreshNetError(Throwable e);

        void loadmoreSuccess(Pair<List<Object>, Boolean> listBooleanPair);

        void loadmoreServerError(Throwable e);

        void loadmoreNetError(Throwable e);

        MultiTypeAdapter getAdapter();
    }

    public static class JDShopPresenter extends BasePresenter<JDShopConstract.JDShopView> {

        private JDShopDataSource jdShopDataSource;
        private IntegralDataSource integralDataSource;
        private PageInfo pageInfo;

        public JDShopPresenter() {
            jdShopDataSource = new JDShopDataSource();
            integralDataSource = new IntegralDataSource();
            pageInfo = PageInfo.newInstance();
        }

        @Override
        public void bind(JDShopConstract.JDShopView view) {
            super.bind(view);
            UserSession.getInstance()
                    .getUserForRx()
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<User>() {
                        @Override
                        public void accept(User user) throws Exception {
                            getView().onUser(user);
                        }
                    });
        }

        public void refreshInit(User userInfo) {
            Single.zip(
                    getJDIntegralSingle(userInfo),
                    getJDGoodsCategorySingle(),
                    getJDGoodsListRefreshSingle(userInfo), new Function3<OpenApiResult<IntegralUserBean>, OpenApiResult<List<JDGoodsCategoryBean>>, OpenApiResult<JDGoodsListResultBean>, Pair<List<Object>,Boolean>>() {
                        @Override
                        public Pair<List<Object>,Boolean> apply(OpenApiResult<IntegralUserBean> integralUserBeanOpenApiResult, OpenApiResult<List<JDGoodsCategoryBean>> listOpenApiResult, OpenApiResult<JDGoodsListResultBean> jdGoodsListResultBeanOpenApiResult) throws Exception {
                            List<Object> dataList = new ArrayList<>();
                            // 1.积分信息
                            JDIntegralModel integralModel = new JDIntegralModel();
                            integralModel.setIntegralUserBean(integralUserBeanOpenApiResult.getData());
                            dataList.add(integralModel);
                            // 2.产品分类title
                            JDTitleModel categoryTitleModel = new JDTitleModel();
                            categoryTitleModel.setType(JDTitleModel.TYPE_CATEGORY);
                            dataList.add(categoryTitleModel);
                            // 3.分类
                            List<JDGoodsCategoryBean> categoryBeans = listOpenApiResult.getData();
                            List<JDGoodsCategoryModel> categoryModels = new ArrayList<>();
                            for (JDGoodsCategoryBean categoryBean : categoryBeans) {
                                JDGoodsCategoryModel jdGoodsCategoryModel = new JDGoodsCategoryModel();
                                jdGoodsCategoryModel.setCategoryBean(categoryBean);
                                categoryModels.add(jdGoodsCategoryModel);
                            }
                            JDGoodsCategoryModel allCategory = new JDGoodsCategoryModel();
                            categoryModels.add(allCategory);
                            dataList.addAll(categoryModels);
                            // 4.热门兑换title
                            JDTitleModel goodsTitleModel = new JDTitleModel();
                            goodsTitleModel.setType(JDTitleModel.TYPE_HOT);
                            dataList.add(goodsTitleModel);
                            // 5.热门兑换商品
                            List<JDGoodsItemBean> goodsItemBeans = jdGoodsListResultBeanOpenApiResult.getData().getDatas();
                            List<JDGoodsItemModel> goodsItemModels = new ArrayList<>();
                            for (JDGoodsItemBean goodsItemBean : goodsItemBeans) {
                                JDGoodsItemModel goodsItemModel = new JDGoodsItemModel();
                                goodsItemModel.setGoodsItemBean(goodsItemBean);
                                goodsItemModels.add(goodsItemModel);
                                //
                                goodsItemBean.setExchangeRate(integralModel.getIntegralUserBean().getExchangeRate());
                            }
                            // 6.handle divider show
                            for (int i = 0; i < goodsItemModels.size(); i++) {
                                if ((i + 1) % 2 != 0) {
                                    goodsItemModels.get(i).setShowLeftDivider(false);
                                } else {
                                    goodsItemModels.get(i).setShowLeftDivider(true);
                                }
                            }
                            dataList.addAll(goodsItemModels);
                            boolean isEnableLoadmore = goodsItemModels.size() >= pageInfo.getPageSize();
                            return new Pair<>(dataList, isEnableLoadmore);
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<Pair<List<Object>,Boolean>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(Pair<List<Object>,Boolean> datas) {
                            pageInfo.resetPage();
                            getView().refreshInitSuccess(datas);
                        }

                        @Override
                        public void onError(Throwable e) {
                            if (e instanceof CancellationException) {
                                return;
                            }
                            getView().onLoaded();
                            Logger.e(e, "=======> \n" + e.getMessage());
                            if (e instanceof ApiException) {
                                getView().refreshInitServerError(e);
                            } else {
                                getView().refreshInitNetError(e);
                            }
                        }
                    });
        }

        public void refresh(User userInfo) {
            Single.zip(
                    getJDIntegralSingle(userInfo),
                    getJDGoodsCategorySingle(),
                    getJDGoodsListRefreshSingle(userInfo), new Function3<OpenApiResult<IntegralUserBean>, OpenApiResult<List<JDGoodsCategoryBean>>, OpenApiResult<JDGoodsListResultBean>, Pair<List<Object>,Boolean>>() {
                        @Override
                        public Pair<List<Object>,Boolean> apply(OpenApiResult<IntegralUserBean> integralUserBeanOpenApiResult, OpenApiResult<List<JDGoodsCategoryBean>> listOpenApiResult, OpenApiResult<JDGoodsListResultBean> jdGoodsListResultBeanOpenApiResult) throws Exception {
                            List<Object> dataList = new ArrayList<>();
                            // 1.积分信息
                            JDIntegralModel integralModel = new JDIntegralModel();
                            integralModel.setIntegralUserBean(integralUserBeanOpenApiResult.getData());
                            dataList.add(integralModel);
                            // 2.产品分类title
                            JDTitleModel categoryTitleModel = new JDTitleModel();
                            categoryTitleModel.setType(JDTitleModel.TYPE_CATEGORY);
                            dataList.add(categoryTitleModel);
                            // 3.分类
                            List<JDGoodsCategoryBean> categoryBeans = listOpenApiResult.getData();
                            List<JDGoodsCategoryModel> categoryModels = new ArrayList<>();
                            for (JDGoodsCategoryBean categoryBean : categoryBeans) {
                                JDGoodsCategoryModel jdGoodsCategoryModel = new JDGoodsCategoryModel();
                                jdGoodsCategoryModel.setCategoryBean(categoryBean);
                                categoryModels.add(jdGoodsCategoryModel);
                            }
                            JDGoodsCategoryModel allCategory = new JDGoodsCategoryModel();
                            categoryModels.add(allCategory);
                            dataList.addAll(categoryModels);
                            // 4.热门兑换title
                            JDTitleModel goodsTitleModel = new JDTitleModel();
                            goodsTitleModel.setType(JDTitleModel.TYPE_HOT);
                            dataList.add(goodsTitleModel);
                            // 5.热门兑换商品
                            List<JDGoodsItemBean> goodsItemBeans = jdGoodsListResultBeanOpenApiResult.getData().getDatas();
                            List<JDGoodsItemModel> goodsItemModels = new ArrayList<>();
                            for (JDGoodsItemBean goodsItemBean : goodsItemBeans) {
                                JDGoodsItemModel goodsItemModel = new JDGoodsItemModel();
                                goodsItemModel.setGoodsItemBean(goodsItemBean);
                                goodsItemModels.add(goodsItemModel);
                                //
                                goodsItemBean.setExchangeRate(integralModel.getIntegralUserBean().getExchangeRate());
                            }
                            // 6.handle divider show
                            for (int i = 0; i < goodsItemModels.size(); i++) {
                                if ((i + 1) % 2 != 0) {
                                    goodsItemModels.get(i).setShowLeftDivider(false);
                                } else {
                                    goodsItemModels.get(i).setShowLeftDivider(true);
                                }
                            }
                            dataList.addAll(goodsItemModels);
                            boolean isEnableLoadmore = goodsItemModels.size() >= pageInfo.getPageSize();
                            return new Pair<>(dataList, isEnableLoadmore);
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<Pair<List<Object>,Boolean>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(Pair<List<Object>,Boolean> datas) {
                            pageInfo.resetPage();
                            getView().refreshSuccess(datas);
                        }

                        @Override
                        public void onError(Throwable e) {
                            if (e instanceof CancellationException) {
                                return;
                            }
                            getView().onLoaded();
                            if (e instanceof ApiException) {
                                getView().refreshServerError(e);
                            } else {
                                getView().refreshNetError(e);
                            }
                        }
                    });
        }

        public void loadmore(User userInfo) {
            getJDGoodsListLoadmoreSingle(userInfo, pageInfo)
                    .map(new Function<OpenApiResult<JDGoodsListResultBean>, Pair<List<Object>,Boolean>>() {
                        @Override
                        public Pair<List<Object>, Boolean> apply(OpenApiResult<JDGoodsListResultBean> jdGoodsListResultBeanOpenApiResult) throws Exception {
                            JDIntegralModel integralModel = (JDIntegralModel) getView().getAdapter().getItems().get(0);
                            // 加载更多数据
                            List<JDGoodsItemBean> goodsItemBeans = jdGoodsListResultBeanOpenApiResult.getData().getDatas();
                            List<JDGoodsItemModel> goodsItemModels = new ArrayList<>();
                            for (JDGoodsItemBean goodsItemBean : goodsItemBeans) {
                                JDGoodsItemModel goodsItemModel = new JDGoodsItemModel();
                                goodsItemModel.setGoodsItemBean(goodsItemBean);
                                goodsItemModels.add(goodsItemModel);
                                //
                                goodsItemBean.setExchangeRate(integralModel.getIntegralUserBean().getExchangeRate());
                            }
                            // 6.handle divider show
                            // todo : 判断之前的数据
                            int countGoodsModel = 0;
                            List<Object> items = (List<Object>) getView().getAdapter().getItems();
                            for (int i = 0; i < items.size(); i++) {
                                if (items.get(i) instanceof JDGoodsItemModel) {
                                    countGoodsModel++;
                                }
                            }
                            int step = 0;
                            if (countGoodsModel % 2 == 0) {
                                step = 1;
                            } else {
                                step = 0;
                            }
                            for (int i = 0; i < goodsItemModels.size(); i++) {
                                if ((i + step) % 2 != 0) {
                                    goodsItemModels.get(i).setShowLeftDivider(false);
                                } else {
                                    goodsItemModels.get(i).setShowLeftDivider(true);
                                }
                            }
                            List<Object> datas = new ArrayList<>();
                            datas.addAll(goodsItemModels);
                            boolean isEnableLoadmore = goodsItemModels.size() >= pageInfo.getPageSize();
                            return new Pair<>(datas, isEnableLoadmore);
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<Pair<List<Object>, Boolean>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(Pair<List<Object>, Boolean> listBooleanPair) {
                            pageInfo.increasePage();
                            getView().loadmoreSuccess(listBooleanPair);
                        }

                        @Override
                        public void onError(Throwable e) {
                            if (e instanceof CancellationException) {
                                return;
                            }
                            getView().onLoaded();
                            if (e instanceof ApiException) {
                                getView().loadmoreServerError(e);
                            } else {
                                getView().loadmoreNetError(e);
                            }
                        }
                    });
        }

        /**
         * 处理请求成功和异常
         * @return
         */
        private <T> SingleTransformer<OpenApiResult<T>, OpenApiResult<T>> getOpenApiResultTranformer() {
            return new SingleTransformer<OpenApiResult<T>, OpenApiResult<T>>() {
                @Override
                public SingleSource<OpenApiResult<T>> apply(Single<OpenApiResult<T>> upstream) {
                    return upstream
                            .doOnSuccess(new Consumer<OpenApiResult<T>>() {
                                @Override
                                public void accept(OpenApiResult<T> result) throws Exception {
                                    if (result != null && result.isSuccess()) {

                                    } else {
                                        throw new ApiException(result);
                                    }
                                }
                            })
                            .doOnError(new Consumer<Throwable>() {
                                @Override
                                public void accept(Throwable e) throws Exception {

                                }
                            });
                }
            };
        }

        /**
         * 获取积分信息
         *
         * @param user
         * @return
         */
        private Single<OpenApiResult<IntegralUserBean>> getJDIntegralSingle(User user) {
            return Single.just(new RequestUserIntegral())
                    .doOnSuccess(new Consumer<RequestUserIntegral>() {
                        @Override
                        public void accept(RequestUserIntegral requestUserIntegral) throws Exception {
                            requestUserIntegral.setPhone(user.getPhone());
                            requestUserIntegral.setAutograph("123456");
                        }
                    })
                    .flatMap(new Function<RequestUserIntegral, SingleSource<OpenApiResult<IntegralUserBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralUserBean>> apply(RequestUserIntegral requestUserIntegral) throws Exception {
                            return integralDataSource.getUserIntegral(requestUserIntegral)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .compose(getOpenApiResultTranformer());
        }

        /**
         * 获取类别信息
         *
         * @return
         */
        private Single<OpenApiResult<List<JDGoodsCategoryBean>>> getJDGoodsCategorySingle() {
            return Single.just(new RequestJDGoodsCategories())
                    .doOnSuccess(new Consumer<RequestJDGoodsCategories>() {
                        @Override
                        public void accept(RequestJDGoodsCategories requestJDGoodsCategories) throws Exception {
                            requestJDGoodsCategories.setKySign("123456");
                            requestJDGoodsCategories.setRecommendType("0");
                        }
                    })
                    .flatMap(new Function<RequestJDGoodsCategories, SingleSource<OpenApiResult<List<JDGoodsCategoryBean>>>>() {
                        @Override
                        public SingleSource<OpenApiResult<List<JDGoodsCategoryBean>>> apply(RequestJDGoodsCategories requestJDGoodsCategories) throws Exception {
                            return jdShopDataSource.getJDGoodsCategories(requestJDGoodsCategories)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .compose(getOpenApiResultTranformer());

        }

        /**
         * 获取热门兑换，刷新
         *
         * @return
         */
        private Single<OpenApiResult<JDGoodsListResultBean>> getJDGoodsListRefreshSingle(User userInfo) {
            return Single.just(new RequestJDGoodsList())
                    .doOnSuccess(new Consumer<RequestJDGoodsList>() {
                        @Override
                        public void accept(RequestJDGoodsList requestJDGoodsList) throws Exception {
                            requestJDGoodsList.setPageIndex(PageInfo.INDEX_DEFAULT);
                            requestJDGoodsList.setPageSize(PageInfo.SIZE_DEFAULT);
                            requestJDGoodsList.setKySign("123456");
                            requestJDGoodsList.setPhone(userInfo.getPhone());
                            requestJDGoodsList.setRecommendType("1");
                        }
                    })
                    .flatMap(new Function<RequestJDGoodsList, SingleSource<OpenApiResult<JDGoodsListResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<JDGoodsListResultBean>> apply(RequestJDGoodsList requestJDGoodsList) throws Exception {
                            return jdShopDataSource.getJDGoodsList(requestJDGoodsList)
                                    .compose(getView().bindToLifecycleDestroy())
                                    .doOnSuccess(new Consumer<OpenApiResult<JDGoodsListResultBean>>() {
                                        @Override
                                        public void accept(OpenApiResult<JDGoodsListResultBean> jdGoodsListResultBeanOpenApiResult) throws Exception {
                                            if (jdGoodsListResultBeanOpenApiResult.isSuccess()) {
                                                List<JDGoodsItemBean> datas = jdGoodsListResultBeanOpenApiResult.getData().getDatas();
                                                for (JDGoodsItemBean itemBean:
                                                        datas) {
                                                    itemBean.setImagePath("http://img13.360buyimg.com/n0/" + itemBean.getImagePath());
                                                }
                                            }
                                        }
                                    });
                        }
                    })
                    .compose(getOpenApiResultTranformer());
        }

        /**
         * 获取热门兑换, 加载
         *
         * @return
         */
        private Single<OpenApiResult<JDGoodsListResultBean>> getJDGoodsListLoadmoreSingle(User userInfo, PageInfo pageInfo) {
            return Single.just(new RequestJDGoodsList())
                    .doOnSuccess(new Consumer<RequestJDGoodsList>() {
                        @Override
                        public void accept(RequestJDGoodsList requestJDGoodsList) throws Exception {
                            requestJDGoodsList.setPageIndex(pageInfo.getPageIndex());
                            requestJDGoodsList.setPageSize(pageInfo.getPageSize());
                            requestJDGoodsList.setKySign("123456");
                            requestJDGoodsList.setPhone(userInfo.getPhone());
                            requestJDGoodsList.setRecommendType("1");
                        }
                    })
                    .flatMap(new Function<RequestJDGoodsList, SingleSource<OpenApiResult<JDGoodsListResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<JDGoodsListResultBean>> apply(RequestJDGoodsList requestJDGoodsList) throws Exception {
                            return jdShopDataSource.getJDGoodsList(requestJDGoodsList)
                                    .compose(getView().bindToLifecycleDestroy())
                                    .doOnSuccess(new Consumer<OpenApiResult<JDGoodsListResultBean>>() {
                                        @Override
                                        public void accept(OpenApiResult<JDGoodsListResultBean> jdGoodsListResultBeanOpenApiResult) throws Exception {
                                            if (jdGoodsListResultBeanOpenApiResult.isSuccess()) {
                                                List<JDGoodsItemBean> datas = jdGoodsListResultBeanOpenApiResult.getData().getDatas();
                                                for (JDGoodsItemBean itemBean:
                                                     datas) {
                                                    itemBean.setImagePath("http://img13.360buyimg.com/n0/" + itemBean.getImagePath());
                                                }
                                            }
                                        }
                                    });
                        }
                    })
                    .compose(getOpenApiResultTranformer());
        }
    }
}
